package core.pathfinder;

import game.units.Unit;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.Iterator;
import java.util.Vector;

import utils.DBG;
import utils.GameMaths;
import core.rendering.Renderable;

public class Route extends Renderable {
	Vector<RoutePoint> route;
	Iterator<RoutePoint> it;
	RoutePoint begin;
	RoutePoint end;

	public Route() {
		route = new Vector<RoutePoint>();
		this.setPosition(0f, 0f);
	}

	public RoutePoint getNextPoint(RoutePoint p) {
		if (p == begin) {
			if (route.size() > 0) {
				return route.get(0);
			} else {
				return end;
			}
		} else {
			if (p == end) {
				return null;
			}
		}
		if (route.indexOf(p) == (route.size() - 1)) {
			return end;
		} else {
			return route.get(route.indexOf(p) + 1);
		}

	}
	
	public RoutePoint getClosestPoint (Unit u){
		
		Iterator<RoutePoint> it = route.iterator();
		RoutePoint closest = null;
		if (it.hasNext()){
		 closest= it.next();
		}
		int index  = 0;
		while (it.hasNext()){
			index++;
			RoutePoint rp = it.next();
			float distanceClosest = GameMaths.getDistance(closest.getPosition(), new Point((int)u.getX() ,(int) u.getY()));
			float distanceRP = GameMaths.getDistance(rp.getPosition(), new Point((int)u.getX() , (int)u.getY())); 
			
			DBG.showMsg("DistanceA : " + distanceClosest + " DistanceB = " + distanceRP, this);
			if (distanceRP < distanceClosest){
				closest = rp;
				DBG.showMsg("Changing route point " + index, this);
			}
		}
		if (closest == null){
			return end;
		}
		return closest;
	}

	public RoutePoint getFirst() {
		return route.get(0);
	}

	public void add(RoutePoint rp) {
		route.add(rp);
	}
	
	public void addInverse(RoutePoint rp){
		route.add(0, rp);
	}

	public RoutePoint getBegin() {
		return begin;
	}

	public void setBegin(RoutePoint begin) {
		if (begin != null){
		DBG.showMsg("Adding new routePoint : " + begin.xpos + " . "
				+ begin.ypos, this);
		this.begin = begin;
		}
	}

	public RoutePoint getEnd() {
		return end;
	}

	public void setEnd(RoutePoint end) {
		DBG.showMsg("Adding new routePoint : " + end.xpos + " . " + end.ypos,
				this);
		this.end = end;
	}

	public void add(int x, int y) {
		DBG.showMsg("Adding new routePoint : " + x + " . " + y, this);
		try {
			if (!addition_blocked) {
				route.add(new RoutePoint(x, y));
			}
		} catch (Exception e) {
			DBG.showMsg(e.getLocalizedMessage(), this);
		}
	}

	RoutePoint prev_point;
	boolean addition_blocked = false;

	@Override
	public void renderComponent(Graphics2D g2d) {
		// TODO Auto-generated method stub
		addition_blocked = true;
		g2d.setColor(Color.black);
		it = route.iterator();
		prev_point = begin;

		while (it.hasNext()) {
			RoutePoint p = it.next();
			g2d.setColor(Color.blue);
			g2d.drawOval(p.getXpos() - 5, p.getYpos() - 5, 10, 10);
			g2d.drawLine(prev_point.getXpos(), prev_point.getYpos(), p.getXpos(), p.getYpos());
			prev_point = p;
		}

		if (begin != null) {
			g2d.setColor(Color.blue);
			g2d.drawOval(begin.getXpos() - 5, begin.getYpos() - 5, 10, 10);
		}
		try{
		if (end != null) {
			g2d.setColor(Color.blue);
			g2d.drawOval(end.getXpos() - 5, end.getYpos() - 5, 10, 10);
			g2d.drawLine(prev_point.getXpos(), prev_point.getYpos(), end.getXpos(), end.getYpos());
		}
		}catch(Exception e){
			DBG.showMsg("EXCEPTION !!!!!!! ", this);
		}
		addition_blocked = false;
	}

	@Override
	public void updateLogic() {
		// TODO Auto-generated method stub
	}

	public void clean() {
		this.route = null;
		this.route = new Vector<RoutePoint>();
	}

}
